package pers.whj.util.tree;

public class BinaryTreePath implements TreePath {
    public static final char LEFT = '0';
    public static final char RIGHT = '1';
    private StringBuilder mBuilder;
    private int mIndex;

    public BinaryTreePath() {
        mBuilder = new StringBuilder();
        mIndex = 0;
    }

    public BinaryTreePath(String path) {
        this();
        append(path);
    }

    public BinaryTreePath(char[] path) {
        this();
        append(path);
    }

    @Override
    public TreePath append(String path) {
        if (path != null) {
            char c;
            for (int i = 0; i < path.length(); i++) {
                c = path.charAt(i);
                if (validDir(c)) {
                    mBuilder.append(c);
                }
            }
        }
        return this;
    }

    @Override
    public TreePath append(char[] path) {
        if (path != null) {
            for (char value : path) {
                if (validDir(value)) {
                    mBuilder.append(value);
                }
            }
        }
        return this;
    }

    @Override
    public TreePath append(char dir) {
        if (validDir(dir)) {
            mBuilder.append(dir);
        }
        return this;
    }

    @Override
    public TreePath appendUnchecked(String path) {
        mBuilder.append(path);
        return this;
    }

    @Override
    public TreePath appendUnchecked(char[] path) {
        mBuilder.append(path);
        return this;
    }

    @Override
    public TreePath appendUnchecked(char dir) {
        mBuilder.append(dir);
        return this;
    }

    @Override
    public TreePath delete() {
        mBuilder.deleteCharAt(mBuilder.length() - 1);
        return this;
    }

    @Override
    public TreePath delete(int index) {
        mBuilder.deleteCharAt(index);
        return this;
    }

    @Override
    public String getPath() {
        return mBuilder.toString();
    }

    @Override
    public int length() {
        return mBuilder.length();
    }

    @Override
    public int index() {
        return mIndex;
    }

    @Override
    public boolean hasNext() {
        return mIndex < mBuilder.length();
    }

    @Override
    public char next() {
        char c = mBuilder.charAt(mIndex);
        mIndex++;
        return c;
    }

    @Override
    public void reset() {
        mIndex = 0;
    }

    @Override
    public void skipTo(int index) {
        if (index < 0 || index >= mBuilder.length()) {
            index = 0;
        }
        mIndex = index;
    }

    @Override
    public void clear() {
        mBuilder = new StringBuilder();
        mIndex = 0;
    }

    public static boolean validDir(char dir) {
        return dir == LEFT || dir == RIGHT;
    }

    public static String normalize(String treePath) {
        StringBuilder builder = new StringBuilder();
        if (treePath != null) {
            char dir;
            for (int i = 0; i < treePath.length(); i++) {
                dir = treePath.charAt(i);
                if (dir == LEFT || dir == RIGHT) {
                    builder.append(dir);
                }
            }
        }
        return builder.toString();
    }

    public static char[] normalize(char[] treePath) {
        StringBuilder builder = new StringBuilder();
        if (treePath != null) {
            for (char c : treePath) {
                if (c == LEFT || c == RIGHT) {
                    builder.append(c);
                }
            }
        }
        return builder.toString().toCharArray();
    }
}